/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wasolicitudesfiec.logicacontrol.SolicitarCambioCarrera;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.naming.NamingException;
import web.util.Constantes;
import com.sun.rave.web.ui.model.Option;
import entidad.*;
import entidad.cambioCarrera.Solicitudcambiocarrera;
import hero.interfaces.BnNodeValue;
import java.sql.SQLException;
import java.sql.Date;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.context.FacesContext;
import wasolicitudesfiec.CambioCarreraoEspecializacion.SolicitarCambio;
import wasolicitudesfiec.general.MensajeException;
import wasolicitudesfiec.logicacontrol.*;
import web.util.SendMailEspol;

/**
 *
 * @author kabad
 */
public class CTRL_EstudianteSolicitaCambio extends CTRL_Base {

    private final String nombreProceso = Constantes.Modelo.modelo_SolicitarCambioCarrera;
    private SolicitarCambio gui;
    private final String nombreActividad = Constantes.SolicitarCambio.solicitarCambio;
    private int idcarreraActual = 0;
    private int idespecializacionActual = 0;
    private boolean iteracion = false;

    public CTRL_EstudianteSolicitaCambio(SolicitarCambio gui, FacesContext facesContext) {
        super(facesContext);
        this.gui = gui;
    }

    public void inicializar() throws MensajeException {
        gui.getMenu().setTitulo("Formulario " + Constantes.TipoSolicitud.CambioCarrera.toString());
        String instancia;
        instancia = (String) externalContext.getRequestParameterMap().get("instancia");
        if (instancia != null) {
            externalContext.getSessionMap().put("instancia", instancia);
        }
        hLisIteracion();
        /************************************************************
         *Verificar si viene de una iteraccion si es asi hay que precargar la informacion
         ***********************************************************/
        if (isIteracion()) {
            precargarDatosSiEsPosible();
        } else {
            leerCarreraAtual();
            leerCarreras();
        }

    }

    public String getNombreInstanciaProceso() {
        String instancia;
        instancia = (String) externalContext.getSessionMap().get("instancia");
        return instancia;
    }

    private void hLisIteracion() {
        String nombreInstanciaProceso;
        BnNodeValue actividad;
        try {
            nombreInstanciaProceso = getNombreInstanciaProceso();
            if (nombreInstanciaProceso == null) {
                setIteracion(false);
                return;
            }
            this.inicializarInstancia(nombreInstanciaProceso);
            actividad = usrSession.getNode(nombreInstanciaProceso, nombreActividad);

            if (!(actividad != null &&
                    (actividad.getState() == hero.interfaces.Constants.Nd.READY ||
                    actividad.getState() == hero.interfaces.Constants.Nd.ANTICIPABLE))) {
                throw new Exception();
            }
            if (actividad.getStartDate() != null) {
                setIteracion(true);
            } else {
                setIteracion(false);
            }
        } catch (Exception ex) {
            setIteracion(false);
        }
    }

    public boolean isIteracion() {
        return iteracion;
    }

    public void setIteracion(boolean iteracion) {
        this.iteracion = iteracion;
        if (iteracion) {
            gui.getLblCarreraNueva().setVisible(true);
            gui.getLblEspecializacionNueva().setVisible(true);
            gui.getDdlCarrera().setVisible(false);
            gui.getDdlEspecializacion().setVisible(false);
        } else {
            gui.getLblCarreraNueva().setVisible(false);
            gui.getLblEspecializacionNueva().setVisible(false);
            gui.getDdlCarrera().setVisible(true);
            gui.getDdlEspecializacion().setVisible(true);
        }
    }

    public void leerCarreras() {

        Option[] listaOpciones;
        Option tempOption;
        Vector<Parametro> listaCarreras;
        Parametro elemCarrera;
        try {
            listaCarreras = logica.leerTodasLasCarreras();
            listaOpciones = new Option[listaCarreras.size()];
            for (int i = 0; i < listaCarreras.size(); i++) {
                elemCarrera = listaCarreras.get(i);
                tempOption = new Option();
                tempOption.setLabel(elemCarrera.getNombre());
                tempOption.setValue(elemCarrera.getIdParametro());
                listaOpciones[i] = tempOption;
            }
            gui.getDdlCarreraDefaultOptions().setOptions(listaOpciones);
            gui.getDdlCarrera().setSelected(listaOpciones[0].getValue());

        } catch (SQLException ex) {
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void cambioEspecializacion() {

        Option[] listaOpciones;
        Option tempOption;
        Vector<Parametro> listaEspecializacion;
        Parametro elemEspecializacion;
        int idCarrera = gui.getCarreraSeleccionada();
        try {
            listaEspecializacion = logica.leerVariosParametroPorIdfkParent(idCarrera);
            listaOpciones = new Option[listaEspecializacion.size()];
            for (int i = 0; i < listaEspecializacion.size(); i++) {
                elemEspecializacion = listaEspecializacion.get(i);
                tempOption = new Option();
                tempOption.setLabel(elemEspecializacion.getNombre());
                tempOption.setValue((Integer) elemEspecializacion.getIdParametro());
                listaOpciones[i] = tempOption;
            }
            gui.getDdlEspecializacionDefaultOptions().setOptions(listaOpciones);
        } catch (SQLException ex) {
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void leerCarreraAtual() throws MensajeException {
        /// este metodo debe leer la carreraActual del estudiante a traves del web service del csi y almacenarlo en dos
        //variables, para luego llevarlos a la base de datos
        //asumo que lo que devuelve el csi son Strings con los nombres de la carrera

        //revisar que pasa si no es posible obtener la carrera actual del estudiante
        String carreraActual = "Ingeniería en Telemática";
        String especializacionActual = null;
        try {
            if (carreraActual == null) {
                throw new MensajeException("No es posible obtener su carrera actual, por favor intente luego d eunos minutos.");
            //recordar que si no encuentra la carrera o especializacion que haga match con los registros en la base los ids se inicializaron con 0
            }
            Vector<Parametro> listaCarreras;
            Vector<Parametro> listaEspecializaciones;
            Parametro elemCarrera, elemEspecializacion;

            listaCarreras = logica.leerTodasLasCarreras();
            for (int i = 0; i < listaCarreras.size(); i++) {
                elemCarrera = listaCarreras.get(i);
                if (elemCarrera.getNombre().compareToIgnoreCase(carreraActual) == 0) {
                    idcarreraActual = elemCarrera.getIdParametro();
                    listaEspecializaciones = logica.leerVariosParametroPorIdfkParent(idcarreraActual);
                    for (int j = 0; j < listaEspecializaciones.size(); j++) {
                        elemEspecializacion = listaEspecializaciones.get(j);
                        if (elemEspecializacion.getNombre().compareToIgnoreCase(especializacionActual) == 0) {
                            idespecializacionActual = elemEspecializacion.getIdParametro();
                            break;
                        }
                    }
                    break;
                }
            }
            if (idcarreraActual != 0 && idespecializacionActual != 0) {
                gui.getLblCarreraActual().setText(carreraActual + " especialización " + especializacionActual);
            } else if (idcarreraActual != 0 && idespecializacionActual == 0) {
                gui.getLblCarreraActual().setText(carreraActual);
            } else {
                throw new MensajeException("No es posible encontrar su carrera actual dentro de nuestra base de datos");
            }
        } catch (MensajeException ex) {
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace();
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void precargarDatosSiEsPosible() throws MensajeException {
        BnNodeValue actividad;
        String nombreInstanciaProceso;
        Solicitudcambiocarrera solicitud;
        int idSolicitudAyudantia;
        try {
            nombreInstanciaProceso = getNombreInstanciaProceso();
            if (nombreInstanciaProceso != null) {
                this.inicializarInstancia(nombreInstanciaProceso);
            }
            actividad = usrSession.getNode(nombreInstanciaProceso, nombreActividad);
            if (!(actividad != null &&
                    (actividad.getState() == hero.interfaces.Constants.Nd.READY ||
                    actividad.getState() == hero.interfaces.Constants.Nd.ANTICIPABLE))) {
                throw new Exception();
            }
            if (actividad.getStartDate() != null) {
                idSolicitudAyudantia = Integer.parseInt(prjSession.getProperty(Constantes.Atributo.idSolicitudProceso).getTheValue());
                solicitud = logica.getLogCambioCarrera().leerSolicitudCambioNivel2(idSolicitudAyudantia);
                gui.getLblCarreraActual().setText(solicitud.getCarreraActual().getNombre());
                if (solicitud.getCarreraNueva().getFkIdParent() != 0) {
                    gui.getLblCarreraNueva().setText(logica.leerParametro(solicitud.getCarreraNueva().getFkIdParent()).getNombre());
                    gui.getLblEspecializacionNueva().setText(logica.leerParametro(solicitud.getFkIdCarreraNueva()).getNombre());
                }else{
                 gui.getLblCarreraNueva().setText(logica.leerParametro(solicitud.getFkIdCarreraNueva()).getNombre());
                gui.getLblEspecializacionNueva().setText("Sin especialización");

                }
                gui.getMenu().setTitulo(nombreProceso + "_" + idSolicitudAyudantia + ": " + nombreActividad);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
            throw new MensajeException(Constantes.Mensajes.noInicia);
        }
    }

    private Solicitudcambiocarrera llenarDatosActividadEstudianteSolicitaCambio(Solicitudcambiocarrera solicitudtmp) throws MensajeException {
        Solicitudcambiocarrera solicitud = null;
        try {
            if (solicitudtmp == null) {
                solicitud = new Solicitudcambiocarrera();
            } else {
                solicitud = solicitudtmp;
            }
            Vector<Parametro> listaEspecializacion = null;
            int idEspecializacion;

            if (!isIteracion()) {
                int idCarrera = (Integer) gui.getDdlCarrera().getSelected();
                listaEspecializacion = logica.leerVariosParametroPorIdfkParent(idCarrera);
                int idPersona = logica.leerPersonaPorUsuario(usuario.getUsuario()).getIdPersona();
                Solicitudcambiocarrera solicitudexistente = logica.getLogCambioCarrera().leerSolicitudCambio(idPersona, Constantes.EstadoSolicitud.Activa.toString());
                if (solicitudexistente != null) {
                    throw new MensajeException("No es posible iniciar la solicitud. Actualmente posee una solicitud de cambio de carrera/especialización activa. " +
                            "'" + this.nombreProceso + "_" + solicitudexistente.getIdSolicitudCambioCarrera() + "'");
                }
                Estudiante estudiante = logica.leerEstudiantePorUsuario(usuario.getUsuario());
                solicitud.setFkidestudiante(estudiante.getIdEstudiante());
                solicitud.setEstado(Constantes.EstadoSolicitud.Activa.toString());
                if (idespecializacionActual == 0) {
                    solicitud.setFkIdCarreraActual(idcarreraActual);
                } else {
                    solicitud.setFkIdCarreraActual(idespecializacionActual);
                }
                if (listaEspecializacion.size() == 0) {
                    solicitud.setFkIdCarreraNueva(idCarrera);
                } else {
                    idEspecializacion = new Integer((String) gui.getDdlEspecializacion().getSelected());
                    solicitud.setFkIdCarreraNueva(idEspecializacion);
                }
                //verificamos que la nueva carrera escogida no sea igual a la actual
                if (solicitud.getFkIdCarreraNueva() == solicitud.getFkIdCarreraActual()) {
                    throw new MensajeException("No es posible enviar la solicitud. Actualmente ya pertence a la carrera seleccionada.");
                }
            }
            solicitud.setObservacionEstudiante((String) gui.getTxtObservacion().getText());
        } catch (MensajeException ex) {
            throw ex;
        } catch (SQLException ex) {
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
        }
        return solicitud;
    }

    public boolean guardarActividadEstudianteSolicitaCambio() throws MensajeException {
        String nombreInstanciaProceso;
        BnNodeValue actividad;
        Solicitudcambiocarrera solicitud = new Solicitudcambiocarrera();
        int idSolicitud;
        try {
            nombreInstanciaProceso = getNombreInstanciaProceso();
            if (isIteracion() && (nombreInstanciaProceso != null)) {
                this.inicializarInstancia(nombreInstanciaProceso);
                idSolicitud = Integer.parseInt(prjSession.getProperty(Constantes.Atributo.idSolicitudProceso).getTheValue());
                solicitud = logica.getLogCambioCarrera().leerSolicitudCambioNivel2(idSolicitud);
                solicitud = llenarDatosActividadEstudianteSolicitaCambio(solicitud);
                solicitud = logica.getLogCambioCarrera().guardarYClonarSolicitudCambio(solicitud);
            }
            if ((nombreInstanciaProceso == null) && (!isIteracion())) {
                solicitud = llenarDatosActividadEstudianteSolicitaCambio(null);
                prjSession.instantiateProject(nombreProceso);
                nombreInstanciaProceso = prjSession.getName();
                solicitud.setNombreinstanciaproceso(nombreInstanciaProceso);
                solicitud = logica.getLogCambioCarrera().nuevoSolicitudCambio(solicitud);
                prjSession.setProperty(Constantes.Atributo.idSolicitudProceso, solicitud.getIdSolicitudCambioCarrera() + "");
                solicitud = logica.getLogCambioCarrera().clonarSolicitudCambio(solicitud);
            }
            actividad = usrSession.getNode(nombreInstanciaProceso, nombreActividad);
            if (!(actividad != null &&
                    (actividad.getState() == hero.interfaces.Constants.Nd.READY ||
                    actividad.getState() == hero.interfaces.Constants.Nd.ANTICIPABLE))) {
                throw new Exception();
            }
            prjSession.setNodeProperty(nombreActividad, Constantes.Atributo.idSolicitudActividad, solicitud.getIdSolicitudCambioCarrera() + "");
            usrSession.startActivity(nombreInstanciaProceso, nombreActividad);
            usrSession.terminateActivity(nombreInstanciaProceso, nombreActividad);

            //enviar mail de notificacion
            int idSubdecano = new Integer(logica.leerConfiguracionPorNombre(Constantes.Configuracion.Subdecano.getNombreEnBD()).getValor());
            String to = logica.leerPersona(idSubdecano).getCorreo();
            int idSolicitudCompleta = solicitud.getFkParent();
            solicitud = logica.getLogCambioCarrera().leerSolicitudCambioNivel2(idSolicitudCompleta);
            String subject = Constantes.MensajesCorreo.tituloCorreo + "Revisión de Solicitud de Cambio de Carrera pendiente";
            String message = Constantes.TipoSolicitud.CambioCarrera + "_" + solicitud.getIdSolicitudCambioCarrera() + ": " +
                    Constantes.SolicitarCambio.revisarSolicitud + "\n\n" + "Título: " + solicitud.toString() + "\n" +
                    "Solicitante: " + logica.leerPersona(solicitud.getFkidestudiante()).toString() + "\n\n" +
                    "La solicitud está en espera de su evaluación." +
                    "\n\n" + "Puede realizar la actividad dirigiéndose a la sección actividades pendientes del sistema."
                    + Constantes.MensajesCorreo.referenciaSistema;
            SendMailEspol sendMail = new SendMailEspol(to, subject, message);
            sendMail.send();
            return true;
        } catch (MensajeException ex) {
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace();
            Logger.getLogger(CTRL_EstudianteSolicitaCambio.class.getName()).log(Level.SEVERE, null, ex);
            throw new MensajeException(Constantes.Mensajes.noGuarda);
        }
    }
}
